
#include "kbmouse.h"

Keytype::Keytype(KbMouse *parent, QString lower, QString upper, int ctrl, int alt, int width) : QToolButton()
{
    this->setText(lower);
    lowerCase = lower;

    if(upper.length() == 0)
        upperCase = lower;
    else
        upperCase = upper;

    ctrlValue = ctrl;
    altValue = alt;

    if(lower.compare(CapsLock) == 0) {
        this->setCheckable(true);
    }
    int minsize = 42;
    int ht = 25;
    this->setMinimumSize(QSize(minsize, ht));
    if(width) {
        int len = this->text().length();
        if(len*width > minsize) {
            this->setMinimumSize(QSize(len*width, ht));
        }
    }
    connect(this, SIGNAL(clicked(bool)), this, SLOT(capslock(bool)));
    connect(this, SIGNAL(clicked()), this, SLOT(keyclick()));
    connect(this, SIGNAL(keyclick(Keytype*)), parent, SLOT(keyclick(Keytype*)));
}

void Keytype::keyclick()
{
    emit keyclick(this);
}

void Keytype::capslock(bool on)
{
    capslocked = on;
}

KbMouse::KbMouse(QWidget *parent)
    : QWidget(parent), shiftPressed(false), altPressed(false), ctrlPressed(false)
{
    int n = 0;

    layout.addWidget(new Keytype(this, "ESC", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F1", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F2", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F3", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F4", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F5", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F6", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F7", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F8", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F9", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F10", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F11", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "F12", "", -1, -1), 0, n++);
    layout.addWidget(new Keytype(this, "PrSc", "", -1, -1), 0, n++);
    //layout.addWidget(new Keytype(this, "ScLk", "", -1, -1), 0, n++);
    n = 0;
    layout.addWidget(new Keytype(this, "`", "~", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "1", "!", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "2", "@", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "3", "#", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "4", "$", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "5", "%", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "6", "^", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "7", "&&", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "8", "*", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "9", "(", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "0", ")", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "-", "_", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "=", "+", -1, -1), 1, n++);
    layout.addWidget(new Keytype(this, "BSP", "", -1, -1), 1, n++, 1, 2);
    n = 0;
    layout.addWidget(new Keytype(this, "Tab", "", -1, -1), 2, n++, 1, 1);
    layout.addWidget(new Keytype(this, "q", "Q", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "w", "W", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "e", "E", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "r", "R", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "t", "T", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "y", "Y", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "u", "U", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "i", "I", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "o", "O", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "p", "P", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "[", "{", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "]", "}", -1, -1), 2, n++);
    layout.addWidget(new Keytype(this, "\\", "|", -1, -1), 2, n++);
    n = 0;
    layout.addWidget(new Keytype(this, CapsLock, "", -1, -1), 3, n++, 1, 1);
    layout.addWidget(new Keytype(this, "a", "A", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "s", "S", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "d", "D", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "f", "F", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "g", "G", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "h", "H", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "j", "J", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "k", "K", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "l", "L", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, ";", ":", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "'", "\"", -1, -1), 3, n++);
    layout.addWidget(new Keytype(this, "Enter", "", -1, -1, 18), 3, n++, 1, 2);
    n = 0;
    layout.addWidget(new Keytype(this, ShiftKey, "", -1, -1), 4, n++, 1, 1);
    layout.addWidget(new Keytype(this, "z", "Z", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "x", "X", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "c", "C", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "v", "V", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "b", "B", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "n", "N", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "m", "M", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, ",", "<", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, ".", ">", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "/", "?", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "PgUp", "", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "UP", "", -1, -1), 4, n++);
    layout.addWidget(new Keytype(this, "PgDn", "", -1, -1), 4, n++);
    n = 0;
    layout.addWidget(new Keytype(this, CtrlKey, "", -1, -1), 5, n++, 1, 2);
    layout.addWidget(new Keytype(this, AltKey,  "", -1, -1), 5, n++, 1, 2);
    layout.addWidget(new Keytype(this, "           ", "", -1, -1, 26), 5, n++, 1, 10);
    n += 5;
    //layout.addWidget(new Keytype(this, "Start", "", -1, -1), 5, n++, 1, 2);
    layout.addWidget(new Keytype(this, "Home", "", -1, -1), 5, n++);
    layout.addWidget(new Keytype(this, "End", "", -1, -1), 5, n++);
    layout.addWidget(new Keytype(this, "Ins", "", -1, -1), 5, n++);
    layout.addWidget(new Keytype(this, "<-", "", -1, -1, 3), 5, n++);
    layout.addWidget(new Keytype(this, "DN", "", -1, -1, 3), 5, n++);
    layout.addWidget(new Keytype(this, "->", "", -1, -1, 3), 5, n++);

    setLayout(&layout);
}

KbMouse::~KbMouse()
{
}

Keytype *KbMouse::findKey(QString name)
{
    QList<Keytype *> keys;
    keys = findChildren<Keytype *>();
    foreach(Keytype *kt, keys) {
        if(kt->text().compare(name) == 0) {
            return kt;
        }
    }
    return 0;
}

void KbMouse::clearAltKey()
{
    Keytype *key = findKey(AltKey);
    key->setCheckable(false);
    key->setChecked(false);
    altPressed = false;
    key->repaint();
    QApplication::processEvents();
}

void KbMouse::clearCtrlKey()
{
    Keytype *key = findKey(CtrlKey);
    key->setCheckable(false);
    key->setChecked(false);
    ctrlPressed = false;
    key->repaint();
    QApplication::processEvents();
}

void KbMouse::clearShiftKey()
{
    Keytype *key = findKey(ShiftKey);
    key->setCheckable(false);
    key->setChecked(false);
    shiftPressed = false;
    key->repaint();
    QApplication::processEvents();
}

void KbMouse::keyclick(Keytype *type)
{
    QList<Keytype *> keys;
    QString k;

    if(altPressed) {
        clearAltKey();
        k = type->altValue;
    }
    else if(ctrlPressed) {
        clearCtrlKey();
        k = type->ctrlValue;
    }
    else if(shiftPressed) {
        clearShiftKey();
        k = type->upperCase;
    }
    else {
        k = type->text();
    }

    if(type->text().compare(CapsLock) == 0) {
        keys = findChildren<Keytype *>();
        foreach(Keytype *kt, keys) {
            if(type->capslocked) {
                kt->setText(kt->upperCase);
            }
            else {
                kt->setText(kt->lowerCase);
            }
        }
        QApplication::processEvents();
    }
    else if(type->text().compare(ShiftKey) == 0) {
        type->setCheckable(true);
        type->setChecked(true);
        shiftPressed = true;
    }
    else if(type->text().compare(CtrlKey) == 0) {
        type->setCheckable(true);
        type->setChecked(true);
        ctrlPressed = true;
    }
    else if(type->text().compare(AltKey) == 0) {
        type->setCheckable(true);
        type->setChecked(true);
        altPressed = true;
    }
    else {
        //
        // send key k to program
        //
        qDebug() << "Key" << k;
    }
}
